package mongox

import (
	"fmt"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
)

type MongoFilter struct {
	SortBy     string
	SortMode   int8
	Limit      *int64
	Skip       *int64
	Filter     map[string]interface{}
	RegexFiler map[string]string
	Projection interface{}
}

// Deprecated:  replace by [mongox.IntRange].
type TimeRange struct {
	Min *int64 `json:"min,optional"`
	Max *int64 `json:"max,optional"`
}

type SelectController[T int64 | string] struct {
	Values  []T  `json:"values,optional"`
	Exclude bool `json:"exclude,optional"`
}

func (s *SelectController[T]) Filter() bson.M {
	if s.Values == nil {
		s.Values = []T{}
	}
	if s.Exclude {
		return bson.M{"$nin": s.Values}
	}
	return bson.M{"$in": s.Values}
}

type StatItem struct {
	Id    string `bson:"_id"`
	Count int32  `bson:"count"`
}

func ToOIds(ids []string) ([]primitive.ObjectID, error) {
	if len(ids) == 0 {
		return nil, nil
	}
	items := make([]primitive.ObjectID, 0, len(ids))
	for _, v := range ids {
		oid, err := primitive.ObjectIDFromHex(v)
		if err != nil {
			return nil, fmt.Errorf("ObjectIDFromHex error:%w id:%s", err, v)
		}
		items = append(items, oid)
	}

	return items, nil
}

// Deprecated:  replace by [mongox.IntRange FilterM].
func TimeRangeFilter(timeRange TimeRange) bson.M {
	timeFilter := bson.M{}
	if timeRange.Min != nil {
		timeFilter["$gte"] = *timeRange.Min
	}
	if timeRange.Max != nil {
		timeFilter["$lt"] = *timeRange.Max
	}
	return timeFilter
}

// Deprecated:  replace by [mongox.IntRange FilterD].
func TimeRangeFilterD(timeRange TimeRange) bson.D {
	timeFilter := bson.D{}
	if timeRange.Min != nil {
		timeFilter = append(timeFilter, bson.E{"$gte", *timeRange.Min})
	}
	if timeRange.Max != nil {
		timeFilter = append(timeFilter, bson.E{"$lt", *timeRange.Max})
	}
	return timeFilter
}

func TimeFilter(startTime, endTime int64) bson.M {
	createTimeFilter := bson.M{}
	if startTime > 0 {
		createTimeFilter["$gte"] = startTime
	}

	if endTime > 0 {
		createTimeFilter["$lt"] = endTime
	}
	return createTimeFilter
}
